const express = require('express');
const router = express.Router();
const tencentIMService = require('../utils/tencent-im');
const { logger } = require('../utils/logger');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const xml2js = require('xml2js');
const userAuthService = require('../services/userAuthService');
const { cacheFactory } = require('../utils/cache');
const { generateId } = require('../utils/idGenerator');

// 获取缓存实例
let cache = null;

// 初始化缓存实例
async function initCache() {
  if (!cache) {
    cache = await cacheFactory.getCache();
    logger.info('缓存实例初始化成功');
  }
  return cache;
}

/**
 * @route POST /api/auth/generate-usersig
 * @description 生成腾讯云IM用户签名
 * @body {string} userId - 用户ID
 * @body {number} [expire=15552000] - 签名有效期（秒），默认180天
 */
router.post('/generate-usersig', async (req, res) => {
  try {
    const { userId, expire = 15552000 } = req.body;

    // 参数验证
    if (!userId) {
      return res.status(400).json({
        code: 400,
        message: '用户ID不能为空',
        data: {}
      });
    }

    if (!tencentIMService.isConfigured()) {
      return res.status(503).json({
        code: 503,
        message: '腾讯云IM服务未配置，请联系管理员',
        data: {}
      });
    }

    // 生成UserSig
    const userSigData = tencentIMService.generateUserSig(userId, expire);

    logger.info(`生成UserSig成功 - 用户: ${userId}, 有效期: ${expire}秒`);

    res.status(200).json({
      code: 200,
      message: '成功',
      data: userSigData
    });

  } catch (error) {
    logger.error('生成UserSig失败:', error);

    res.status(500).json({
      code: 500,
      message: error.message || '生成签名失败',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/verify-usersig
 * @description 验证用户签名是否有效
 * @body {string} userId - 用户ID
 * @body {string} userSig - 用户签名
 */
router.post('/verify-usersig', async (req, res) => {
  try {
    const { userId, userSig } = req.body;

    // 参数验证
    if (!userId || !userSig) {
      return res.status(400).json({
        code: 400,
        message: '用户ID和用户签名不能为空',
        data: {}
      });
    }

    if (!tencentIMService.isConfigured()) {
      return res.status(503).json({
        code: 503,
        message: '腾讯云IM服务未配置',
        data: {}
      });
    }

    // 验证UserSig
    const isValid = tencentIMService.verifyUserSig(userSig, userId);

    logger.info(`验证UserSig - 用户: ${userId}, 结果: ${isValid ? '有效' : '无效'}`);

    res.status(200).json({
      code: 200,
      message: '成功',
      data: {
        isValid,
        userId
      }
    });

  } catch (error) {
    logger.error('验证UserSig失败:', error);

    res.status(500).json({
      code: 500,
      message: error.message || '验证签名失败',
      data: {}
    });
  }
});

/**
 * @route GET /api/auth/config
 * @description 获取腾讯云IM配置信息（不包含敏感信息）
 */
router.get('/config', async (req, res) => {
  try {
    const config = tencentIMService.getConfig();

    res.status(200).json({
      code: 200,
      message: '成功',
      data: config
    });

  } catch (error) {
    logger.error('获取配置信息失败:', error);

    res.status(500).json({
      code: 500,
      message: error.message || '获取配置信息失败',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/login
 * @description 手机号/密码登录
 * @body {string} phone - 手机号
 * @body {string} password - 密码
 */
router.post('/login', async (req, res) => {
  try {
    const { phone, password } = req.body;

    // 参数验证
    if (!phone || !password) {
      return res.status(400).json({
        code: 400,
        message: '手机号和密码不能为空',
        data: {}
      });
    }

    // 验证手机号格式
    const phoneRegex = /^1[3-9]\d{9}$/;
    if (!phoneRegex.test(phone)) {
      return res.status(400).json({
        code: 400,
        message: '手机号格式不正确',
        data: {}
      });
    }

    // 模拟用户验证（实际项目中应该查询数据库）
    // 这里使用固定密码进行演示
    const validPassword = await bcrypt.compare(password, await bcrypt.hash('123456', 10));

    if (!validPassword) {
      return res.status(401).json({
        code: 401,
        message: '手机号或密码错误',
        data: {}
      });
    }

    // 生成JWT token
    const token = jwt.sign(
      {
        userId: `user_${phone.substring(7)}`,
        phone: phone,
        type: 'phone'
      },
      process.env.JWT_SECRET || 'fallback-secret',
      { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
    );

    logger.info(`用户登录成功 - 手机号: ${phone}`);

    res.status(200).json({
      code: 200,
      message: '登录成功',
      data: {
        token,
        user: {
          id: `user_${phone.substring(7)}`,
          name: `用户${phone.substring(7)}`,
          phone: phone,
          avatar: '/static/images/avatar/1.jpg'
        }
      }
    });

  } catch (error) {
    logger.error('用户登录失败:', error);

    res.status(500).json({
      code: 500,
      message: error.message || '登录失败，请稍后重试',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/wechat-miniprogram
 * @description 微信小程序登录
 * @body {string} code - 微信小程序登录code
 */
router.post('/wechat-miniprogram', async (req, res) => {
  try {
    const { code } = req.body;

    if (!code) {
      return res.status(400).json({
        code: 400,
        message: '微信登录code不能为空',
        data: {}
      });
    }

    // 模拟微信小程序登录（实际项目中应该调用微信API）
    // 这里返回模拟数据
    const openid = `wx_mini_${Date.now()}`;

    const token = jwt.sign(
      {
        userId: `user_${openid.substring(10)}`,
        openid: openid,
        type: 'wechat_mini'
      },
      process.env.JWT_SECRET || 'fallback-secret',
      { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
    );

    logger.info(`微信小程序登录成功 - openid: ${openid}`);

    res.status(200).json({
      code: 200,
      message: '微信小程序登录成功',
      data: {
        token,
        user: {
          id: `user_${openid.substring(10)}`,
          name: '微信用户',
          avatar: '/static/images/avatar/2.jpg',
          openid: openid
        }
      }
    });

  } catch (error) {
    logger.error('微信小程序登录失败:', error);

    res.status(500).json({
      code: 500,
      message: error.message || '微信登录失败，请稍后重试',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/wechat-official
 * @description 微信公众号登录
 * @body {string} code - 微信公众号授权code
 */
router.post('/wechat-official', async (req, res) => {
  try {
    const { code } = req.body;

    if (!code) {
      return res.status(400).json({
        code: 400,
        message: '微信公众号授权code不能为空',
        data: {}
      });
    }

    // 模拟微信公众号登录（实际项目中应该调用微信API）
    // 这里返回模拟数据
    const openid = `wx_official_${Date.now()}`;

    const token = jwt.sign(
      {
        userId: `user_${openid.substring(13)}`,
        openid: openid,
        type: 'wechat_official'
      },
      process.env.JWT_SECRET || 'fallback-secret',
      { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
    );

    logger.info(`微信公众号登录成功 - openid: ${openid}`);

    res.status(200).json({
      code: 200,
      message: '微信公众号登录成功',
      data: {
        token,
        user: {
          id: `user_${openid.substring(13)}`,
          name: '公众号用户',
          avatar: '/static/images/avatar/3.jpg',
          openid: openid
        }
      }
    });

  } catch (error) {
    logger.error('微信公众号登录失败:', error);

    res.status(500).json({
      code: 500,
      message: error.message || '微信公众号登录失败，请稍后重试',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/verify-token
 * @description 验证JWT token
 * @body {string} token - JWT token
 */
router.post('/verify-token', async (req, res) => {
  try {
    const { token } = req.body;

    if (!token) {
      return res.status(400).json({
        code: 400,
        message: 'token不能为空',
        data: {}
      });
    }

    const decoded = jwt.verify(token, process.env.JWT_SECRET || 'fallback-secret');

    res.status(200).json({
      code: 200,
      message: '成功',
      data: {
        valid: true,
        user: decoded
      }
    });

  } catch (error) {
    res.status(200).json({
      code: 200,
      message: '成功',
      data: {
        valid: false,
        error: 'token无效或已过期'
      }
    });
  }
});

// 存储公众号登录验证码状态（实际项目中应该使用Redis等缓存）
const wechatOfficialCodes = new Map();

/**
 * @route POST /api/auth/wechat-official/code
 * @description 获取公众号登录验证码
 * @body {string} openid - 用户openid（可选）
 */
router.post('/wechat-official/code', async (req, res) => {
  try {
    // 生成随机验证码（20位数字字母组合）
    const code = generateId(20);
    const cacheInstance = await initCache();
    const captchaKey = `captcha:${code}`;
    
    await cacheInstance.set(captchaKey, {
      code: code,
      status: 'pending',
      userId: null,
      openid: null
    }, 300); // 5分钟过期时间（300秒）
    res.status(200).json({
      code: 200,
      message: '成功',
      data: {
        code: code,
        expiresIn: 5 * 60 // 5分钟
      }
    });

  } catch (error) {
    logger.error('生成公众号验证码失败:', error);

    res.status(500).json({
      code: 500,
      message: '生成验证码失败，请稍后重试',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/wechat-official/message
 * @description 处理微信公众号消息（XML格式），解析获取openid
 */
router.post('/wechat-official/message', async (req, res) => {
  try {
    // 检查请求内容类型是否为XML
    const contentType = req.headers['content-type'] || '';
    if (!contentType.includes('text/xml') && !contentType.includes('application/xml')) {
      return res.status(400).json({
        code: 400,
        message: '请求内容类型必须是XML',
        data: {}
      });
    }

    // 获取XML原始数据
    let xmlData = '';
    req.on('data', chunk => {
      xmlData += chunk.toString();
    });

    req.on('end', async () => {
      try {
        // 解析XML数据
        const parser = new xml2js.Parser({ explicitArray: false, ignoreAttrs: true });
        const result = await parser.parseStringPromise(xmlData);

        // 提取微信公众号消息的关键字段
        const xmlMessage = result.xml;
        if (!xmlMessage) {
          return res.status(400).json({
            code: 400,
            message: 'XML格式不正确，缺少xml根节点',
            data: {}
          });
        }

        // 获取openid（FromUserName）
        const openid = xmlMessage.FromUserName;
        const toUserName = xmlMessage.ToUserName;
        const msgType = xmlMessage.MsgType;
        const content = xmlMessage.Content;

        if (!openid) {
          return res.status(400).json({
            code: 400,
            message: 'XML消息中缺少FromUserName（openid）字段',
            data: {}
          });
        }
        // 存储信息
        await userAuthService.createOrUpdate({
          auth_type: 'wechat',
          openid: openid,
          code: content,
          unionid: null,
          access_token: null,
          refresh_token: null,
          token_expires_at: null,
          user_info: null,
          status: 1
        });

        logger.info(`收到微信公众号消息 - OpenID: ${openid}, 消息类型: ${msgType}, 内容: ${content}`);

        // 检查消息内容是否为指定格式的验证码（8位大写字母和数字组合）
        let responseContent = '消息接收成功';
        
        // 格式验证：必须是20位，且只包含小写字母和数字
        const isValidFormat = content && content.length === 20 && /^[a-z0-9]{20}$/.test(content);
        
        if (!isValidFormat) {
          responseContent = '消息格式不正确';
          logger.warn(`消息格式验证失败 - OpenID: ${openid}, 内容: ${content}`);
        } else {
          try {
            // 格式验证通过，执行验证码存储逻辑
            const cacheInstance = await initCache();
            const captchaKey = `captcha:${content}`;
            
            await cacheInstance.set(captchaKey, {
              code: content,
              status: 'pending',
              userId: null,
              openid: openid
            }, 300); // 5分钟过期时间（300秒）

            responseContent = `登录成功`;
            logger.info(`验证码存储成功 - OpenID: ${openid}, 验证码: ${content}`);
          } catch (redisError) {
            logger.error('存储验证码到Redis失败:', redisError);
            responseContent = '消息接收成功，但验证码存储失败';
          }
        }

        // 构建响应XML（根据微信公众平台要求）
        const responseXml = `
          <xml>
            <ToUserName><![CDATA[${openid}]]></ToUserName>
            <FromUserName><![CDATA[${toUserName}]]></FromUserName>
            <CreateTime>${Math.floor(Date.now() / 1000)}</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[${responseContent}]]></Content>
          </xml>
        `;

        // 设置响应头为XML格式
        res.set('Content-Type', 'text/xml');
        res.send(responseXml);

      } catch (parseError) {
        logger.error('解析XML消息失败:', parseError);

        res.status(400).json({
          code: 400,
          message: 'XML解析失败',
          data: { error: parseError.message }
        });
      }
    });

  } catch (error) {
    logger.error('处理微信公众号消息失败:', error);

    res.status(500).json({
      code: 500,
      message: '处理消息失败，请稍后重试',
      data: {}
    });
  }
});

/**
 * @route POST /api/auth/wechat-official/check
 * @description 检查公众号登录状态
 * @body {string} code - 验证码
 */
router.post('/wechat-official/check', async (req, res) => {
  try {
    const { code } = req.body;

    if (!code) {
      return res.status(400).json({
        code: 400,
        message: '验证码不能为空',
        data: {}
      });
    }
    // 检查验证码是否存在
    const cacheInstance = await initCache();
    const captchaKey = `captcha:${code}`;
    
    let verifyResult = { valid: false, reason: '验证码不存在或已过期' };
    try {
      const captchaData = await cacheInstance.get(captchaKey);
      
      if (captchaData) {
        verifyResult = { valid: true };
      }
    } catch (error) {
      logger.error('验证码验证失败:', error);
      verifyResult.reason = '验证码验证过程中出现错误';
    }

    if (!verifyResult.valid) {
      return res.status(404).json({
        code: 404,
        message: verifyResult.reason,
        data: {}
      });
    }
    // 使用userAuthService.findByCode查找用户认证信息
    const userAuth = await userAuthService.findByCode(code);

    if (!userAuth) {
      return res.status(200).json({
        code: 202,
        message: '验证码暂未绑定用户',
        data: {
          loggedIn: false
        }
      });
    }

    // 检查认证信息状态
    if (userAuth.status === 0) {
      return res.status(200).json({
        code: 202,
        message: '认证信息已被禁用',
        data: {
          loggedIn: false
        }
      });
    }

    // 检查是否已经登录（有用户ID）
    if (userAuth.user_id) {
      // 查找用户信息
      const User = require('../models/User');
      const user = await User.findByPk(userAuth.user_id);
      
      if (user) {
        // 生成JWT token
        const token = jwt.sign(
          {
            userId: user.id,
            type: 'wechat',
            code: code
          },
          process.env.JWT_SECRET,
          { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
        );

        logger.info(`公众号登录验证成功 - 验证码: ${code}, 用户ID: ${user.id}`);

        return res.status(200).json({
          code: 200,
          message: '成功',
          data: {
            loggedIn: true,
            userInfo: {
              id: user.id,
              name: user.username,
              avatar: user.avatar || '/static/images/avatar/3.jpg',
              phone: user.phone
            },
            token: token
          }
        });
      }
    }

    // 如果认证信息存在但用户未登录，返回等待状态
    res.status(200).json({
      code: 200,
      message: '成功',
      data: {
        loggedIn: false,
        message: '等待公众号验证...',
        authInfo: {
          openid: userAuth.openid,
          authType: userAuth.auth_type
        }
      }
    });

  } catch (error) {
    logger.error('检查公众号登录状态失败:', error);

    res.status(500).json({
      code: 500,
      message: '检查登录状态失败，请稍后重试',
      data: {}
    });
  }
});

module.exports = router;